/*   
 *   A   JavaScript   implementation   of   the   Secure   Hash   Algorithm,   SHA-1,   as   defined   
 *   in   FIPS   PUB   180-1   
 *   Version   2.1-BETA   Copyright   Paul   Johnston   2000   -   2002.   
 *   Other   contributors:   Greg   Holt,   Andrew   Kepert,   Ydnar,   Lostinet   
 *   Distributed   under   the   BSD   License   
 *   See   http://pajhome.org.uk/crypt/md5   for   details.   
 */
var sinaSSOEncoder = sinaSSOEncoder || {};
(function() {
    /*   
  *   Configurable   variables.   You   may   need   to   tweak   these   to   be   compatible   with   
  *   the   server-side,   but   the   defaults   work   in   most   cases.   
  */
    var hexcase = 0; /*   hex   output   format.   0   -   lowercase;   1   -   uppercase                 */
    var chrsz = 8; /*   bits   per   input   character.   8   -   ASCII;   16   -   Unicode             */

    /*   
  *   These   are   the   functions   you'll   usually   want   to   call   
  *   They   take   string   arguments   and   return   either   hex   or   base-64   encoded   strings   
  */
    this.hex_sha1 = function(s) {
        return binb2hex(core_sha1(str2binb(s), s.length * chrsz));
    };
    /*   
  *   Calculate   the   SHA-1   of   an   array   of   big-endian   words,   and   a   bit   length   
  */
    var core_sha1 = function(x, len) {
        /*   append   padding   */
        x[len >> 5] |= 0x80 << (24 - len % 32);
        x[((len + 64 >> 9) << 4) + 15] = len;
        
        var w = Array(80);
        var a = 1732584193;
        var b = -271733879;
        var c = -1732584194;
        var d = 271733878;
        var e = -1009589776;
        
        for (var i = 0; i < x.length; i += 16) {
            var olda = a;
            var oldb = b;
            var oldc = c;
            var oldd = d;
            var olde = e;
            
            for (var j = 0; j < 80; j++) {
                if (j < 16)
                    w[j] = x[i + j];
                else
                    w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
                var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), 
                safe_add(safe_add(e, w[j]), sha1_kt(j)));
                e = d;
                d = c;
                c = rol(b, 30);
                b = a;
                a = t;
            }
            
            a = safe_add(a, olda);
            b = safe_add(b, oldb);
            c = safe_add(c, oldc);
            d = safe_add(d, oldd);
            e = safe_add(e, olde);
        }
        return Array(a, b, c, d, e);
    
    };

    /*   
  *   Perform   the   appropriate   triplet   combination   function   for   the   current   
  *   iteration   
  */
    var sha1_ft = function(t, b, c, d) {
        if (t < 20)
            return (b & c) | ((~b) & d);
        if (t < 40)
            return b ^ c ^ d;
        if (t < 60)
            return (b & c) | (b & d) | (c & d);
        return b ^ c ^ d;
    };

    /*   
  *   Determine   the   appropriate   additive   constant   for   the   current   iteration   
  */
    var sha1_kt = function(t) {
        return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : 
        (t < 60) ? -1894007588 : -899497514;
    };
    /*   
  *   Add   integers,   wrapping   at   2^32.   This   uses   16-bit   operations   internally   
  *   to   work   around   bugs   in   some   JS   interpreters.   
  */
    var safe_add = function(x, y) {
        var lsw = (x & 0xFFFF) + (y & 0xFFFF);
        var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
        return (msw << 16) | (lsw & 0xFFFF);
    };

    /*   
  *   Bitwise   rotate   a   32-bit   number   to   the   left.   
  */
    var rol = function(num, cnt) {
        return (num << cnt) | (num >>> (32 - cnt));
    };

    /*   
  *   Convert   an   8-bit   or   16-bit   string   to   an   array   of   big-endian   words   
  *   In   8-bit   function,   characters   >255   have   their   hi-byte   silently   ignored.   
  */
    var str2binb = function(str) {
        var bin = Array();
        var mask = (1 << chrsz) - 1;
        for (var i = 0; i < str.length * chrsz; i += chrsz)
            bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i % 32);
        return bin;
    };


    /*   
  *   Convert   an   array   of   big-endian   words   to   a   hex   string.   
  */
    var binb2hex = function(binarray) {
        var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
        var str = "";
        for (var i = 0; i < binarray.length * 4; i++) 
        {
            str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) + 
            hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF);
        }
        return str;
    };

    /*
  * Convert a string into a base 64 encoded string
  */
    
    this.base64 = {
        encode: function(input) {
            input = "" + input; // Convert to string for encode
            if (input == "")
                return "";
            
            var output = '';
            var chr1, chr2, chr3 = '';
            var enc1, enc2, enc3, enc4 = '';
            var i = 0;
            do {
                chr1 = input.charCodeAt(i++);
                chr2 = input.charCodeAt(i++);
                chr3 = input.charCodeAt(i++);
                enc1 = chr1 >> 2;
                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                enc4 = chr3 & 63;
                if (isNaN(chr2)) {
                    enc3 = enc4 = 64;
                } else if (isNaN(chr3)) {
                    enc4 = 64;
                }
                output = output + this._keys.charAt(enc1) + this._keys.charAt(enc2) + this._keys.charAt(enc3) + this._keys.charAt(enc4);
                chr1 = chr2 = chr3 = '';
                enc1 = enc2 = enc3 = enc4 = '';
            } while (i < input.length);
            return output;
        },
        
        _keys: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
    
    };
}).call(sinaSSOEncoder);
